import * as Cesium from 'cesium'

// 初始化地图场景
export const initViewer = (container) => {
  // 初始化cesium地图对象viewer
  const viewer = new Cesium.Viewer(container, {
    timeline: false, // 是否显示底部时间线控件，常用于动态场景控制
    animation: false, // 是否显示左下角的动画控件（播放、暂停等）
    baseLayerPicker: false, // 是否显示图层选择器，设置为 false 可避免 token 报错
    infoBox: false, // 是否显示点击实体后弹出的信息框
    selectionIndicator: false, // 是否显示实体选中后的绿色选中框
    skyAtmosphere: false, // 是否显示地球外层的光环（大气层效果）
    homeButton: false, // 是否显示“回到初始视角”按钮
    fullscreenButton: false, // 是否显示全屏按钮
    geocoder: false, // 是否显示地名搜索框（搜索地理位置）
    sceneModePicker: false, // 是否显示场景模式切换按钮（2D/3D/哥伦布视图）
    shouldAnimate: true, // 是否启用动画（如时间变化、轨迹动画等）
    navigationHelpButton: false, // 是否显示导航帮助按钮（右上角问号）
  })

  return viewer
}

// 设置后处理效果
export const setScene = (viewer) => {
  // 隐藏太阳和月亮
  viewer.scene.sun.show = false
  viewer.scene.moon.show = false

  // 开启全球光照
  viewer.scene.globe.enableLighting = true

  // 后处理设置
  const stages = viewer.scene.postProcessStages
  stages.fxaa.enabled = true // 抗锯齿

  // 如果浏览器支持“像素化图像渲染”，就将 Cesium 的渲染分辨率提升到当前设备的像素比例，以提高画质。
  if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    viewer.resolutionScale = window.devicePixelRatio
  }

  // 添加亮度调整
  viewer.scene.brightness = viewer.scene.brightness || stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage()) // 工厂方法创建亮度调整特效
  viewer.scene.brightness.enabled = true
  viewer.scene.brightness.uniforms.brightness = 1.2

  // 开启阴影
  viewer.shadows = true
  viewer.shadowMap.darkness = 0.8 //阴影透明度--越大越透明

  // 设置泛光效果（Bloom）
  stages.bloom.enabled = true
  stages.bloom.uniforms.contrast = 255 // 设置对比度。越大越明显地分离高亮区域。
  stages.bloom.uniforms.brightness = 0.02 // 设置整体亮度偏移值。越小越暗。
  stages.bloom.uniforms.glowOnly = false // 是否只显示泛光（Glow）部分。
  stages.bloom.uniforms.delta = 3.1 // 控制模糊采样范围，类似光晕的“半径”。
  stages.bloom.uniforms.sigma = 5 // 控制模糊的强度。越大越模糊。搭配 delta 一起使用，决定泛光的柔和程度。
  stages.bloom.uniforms.stepSize = 0.6 // 模糊采样间距,越小越精细，性能消耗更高；越大越粗糙，但速度快。
  stages.bloom.uniforms.isSelected = false
  stages.bloom.uniforms.selectedBloom = 10
  stages.bloom.uniforms.bloomColor = Cesium.Color.fromCssColorString('#fafafa') // 设置浅灰白色泛光

  // 场景优化
  viewer.scene.globe.depthTestAgainstTerrain = true // 开启深度检测，避免贴地或飞行的模型会穿透地形
  viewer.scene.highDynamicRange = true // 开启HDR，提高图像质量
  viewer.scene.undergroundMode = false // 关闭“地下模式”,视角不会穿透地形以下。
  viewer.scene.terrainProvider.isCreateSkirt = false // 关闭“地形裙边”以提高性能,地形裙边是地形瓦片边缘向下延伸的面，用于遮盖不同级别地形间缝隙。
  viewer.scene.globe.showGroundAtmosphere = false // 关闭“地面大气层效果”。
  viewer.scene.fog.enabled = false // 关闭雾效。

  // 去除 Cesium logo 水印
  viewer.cesiumWidget.creditContainer.style.display = 'none'
}
// 加载多个3dtiles
export const loadTilesets = async (viewer, urls, loadCallback) => {
  const tilesets = urls.map((item) => {
    const { url, options } = item
    let params = { url }
    if (typeof options === 'object') {
      Object.assign(params, options) // 如果有options则合并配置到params中,没有则使用默认配置
    }
    const tile = viewer.scene.primitives.add(new Cesium.Cesium3DTileset(params))
    return tile.readyPromise
  })
  let result = await Promise.all(tilesets)
  loadCallback && loadCallback(result)
}

export const handleDefaultModelEffect = (tile) => {
  // 处理模型着色
  tile.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        ['Number(${Elevation})<20', "color('rgb(25, 211, 226)',0.0)"],// 蓝绿色透明

        ['Number(${Elevation})>20', "color('rgb(25, 211, 226)',1)"], // 蓝绿色不透明
      ],
      show: false,
    },
  })
  const customShader = new Cesium.CustomShader({
    uniforms: {
      maxHeight: {
        type: Cesium.UniformType.FLOAT,
        value: 660.0,
      },
      minHeight: {
        type: Cesium.UniformType.FLOAT,
        value: 520.0,
      },
    },
    mode: Cesium.CustomShaderMode.MODIFY_MATERIAL,
    lightingModel: Cesium.LightingModel.PBR,
    vertexShaderText: /*glsl*/ `
            // 顶点使用默认配置
            void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {}
       `,
    fragmentShaderText: /*glsl*/ `
            void fragmentMain(FragmentInput fsInput,inout czm_modelMaterial material) {
                vec3 positionMC = fsInput.attributes.positionMC;// 模型坐标
          
                float _baseHeight = minHeight; // 物体的基础高度
                float _heightRange = maxHeight; // 高亮的范围(_baseHeight ~ _baseHeight + _heightRange)
             
                float czm_height = positionMC.y - _baseHeight -65.0;

                float baseColor = czm_height / _heightRange;// 基础颜色渐变因子
                float bottomColor= czm_height / _heightRange*2.0;// 底部颜色渐变因子,为baseColor的两倍,变化更明显
                if(czm_height<29.0) {
                    material.diffuse *= vec3(bottomColor); // 颜色乘以底部渐变值，颜色更暗或更亮
                }else{
                  material.diffuse *= vec3(baseColor);  // 高度较高部分，颜色做正常渐变处理
                }
            }
         `,
  })
  tile.customShader = customShader
}

// 视角飞到全局
export const flyToDefaultView = (viewer) => {
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(113.95, 30.19, 34000),
    duration: 2,
    orientation: {
      heading: Cesium.Math.toRadians(35.0),
      pitch: Cesium.Math.toRadians(-37.0),
      roll: 0.0,
    },
  })
}

// 闪烁实体
export const binkEntityMaterial = (entity) => {
  if (!entity.polygon.material.color._value) return
  let initColor = entity.polygon.material.color._value
  // 保存初始透明度值和闪烁方向 true 表示在变透明，false 表示在变回不透明。
  let x = 1
  let flog = true
  entity.polygon.material = new Cesium.ColorMaterialProperty(
    new Cesium.CallbackProperty(() => {
      if (flog) {
        x = x - 0.05
        if (x <= 0) {
          flog = false
        }
      } else {
        x = x + 0.05
        if (x >= 1) {
          flog = true
        }
      }
      return Cesium.Color.RED.withAlpha(x)
    }, false)
  )
  setTimeout(() => {
    entity.polygon.material = initColor
  }, 1500)
}
